From: Jonathan Dieter Date: Mon, 4 Jun 2018 07:48:16 +0000 (+0300) Subject: Modify zckdl so it does the curl calls itself X-Git-Tag: archive/raspbian/1.1.9+ds1-1+rpi1~1^2~257 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=9bacbc76cdea11308d46855ec82cf0a05e83e522;p=zchunk.git Modify zckdl so it does the curl calls itself Signed-off-by: Jonathan Dieter --- diff --git a/src/zck_dl.c b/src/zck_dl.c index 1b81881..b5dc65d 100644 --- a/src/zck_dl.c +++ b/src/zck_dl.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "util_common.h" @@ -103,13 +104,99 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) { static struct argp argp = {options, parse_opt, args_doc, doc}; -int main (int argc, char *argv[]) { - zckCtx *zck_tgt = zck_create(); +int dl_range(CURL *curl, zckDL *dl, char *url, char *range, int is_chunk) { + if(dl == NULL || dl->priv == NULL) { + printf("Struct not defined\n"); + return 0; + } - if(zck_tgt == NULL) - exit(1); + CURLcode res; + + zck_dl_reset(dl); + + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, zck_header_cb); + curl_easy_setopt(curl, CURLOPT_HEADERDATA, dl); + if(is_chunk) + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, zck_write_chunk_cb); + else + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, zck_write_zck_header_cb); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, dl); + curl_easy_setopt(curl, CURLOPT_RANGE, range); + res = curl_easy_perform(curl); + + if(res != CURLE_OK) { + printf("Download failed: %s\n", curl_easy_strerror(res)); + return False; + } + long code; + curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &code); + if (code != 206 && code != 200) { + printf("HTTP Error: %li when download %s\n", code, + url); + return False; + } + + return True; +} + +int dl_byte_range(CURL *curl, zckDL *dl, char *url, int start, int end) { + char *range = zck_get_range(start, end); + return dl_range(curl, dl, url, range, 0); +} + +int dl_bytes(CURL *curl, zckDL *dl, char *url, size_t bytes, size_t start, size_t *buffer_len, int log_level) { + if(start + bytes > *buffer_len) { + int fd = zck_get_fd(dl->zck); + + if(lseek(fd, 0, SEEK_END) == -1) { + printf("Seek to end of temporary file failed: %s\n", + strerror(errno)); + return 0; + } + if(*buffer_len >= start + bytes) + return 1; + if(!dl_byte_range(curl, dl, url, *buffer_len, + (start + bytes - *buffer_len) - 1)) { + printf("Error downloading bytes\n"); + return 0; + } + if(log_level <= ZCK_LOG_DEBUG) + printf("Downloading %lu bytes at position %lu\n", + start+bytes-*buffer_len, *buffer_len); + *buffer_len += start + bytes - *buffer_len; + if(lseek(fd, start, SEEK_SET) == -1) { + printf("Seek to byte %lu of temporary file failed: %s\n", start, + strerror(errno)); + return 0; + } + } + return 1; +} + +int dl_header(CURL *curl, zckDL *dl, char *url, int log_level) { + size_t buffer_len = 0; + size_t start = 0; + + /* Download first two hundred bytes and read magic and hash type */ + if(!dl_bytes(curl, dl, url, get_min_download_size(), start, &buffer_len, log_level)) + return 0; + if(!zck_read_lead(dl->zck)) + return 0; + start = zck_get_lead_length(dl->zck); + printf("Now we need %lu bytes\n", zck_get_header_length(dl->zck) - start); + + if(!dl_bytes(curl, dl, url, zck_get_header_length(dl->zck) - start, + start, &buffer_len, log_level)) + return 0; + if(!zck_read_header(dl->zck)) + return 0; + return 1; +} - zck_dl_global_init(); +int main (int argc, char *argv[]) { + curl_global_init(CURL_GLOBAL_ALL); struct arguments arguments = {0}; @@ -132,11 +219,6 @@ int main (int argc, char *argv[]) { exit(1); } - zckDL *dl = zck_dl_init(); - if(dl == NULL) - exit(1); - dl->zck = zck_tgt; - char *outname_full = calloc(1, strlen(arguments.args[0])+1); memcpy(outname_full, arguments.args[0], strlen(arguments.args[0])); char *outname = basename(outname_full); @@ -147,27 +229,33 @@ int main (int argc, char *argv[]) { exit(1); } free(outname_full); - dl->dst_fd = dst_fd; + zckCtx *zck_tgt = zck_init_adv_read(dst_fd); + if(zck_tgt == NULL) + exit(1); - if(!zck_dl_get_header(zck_tgt, dl, arguments.args[0])) + CURL *curl_ctx = curl_easy_init(); + if(!curl_ctx) { + printf("Unable to allocate %lu bytes for curl context\n", + sizeof(CURL)); exit(1); + } - zck_range_close(&(dl->info)); - if(!zck_dl_copy_src_chunks(&(dl->info), zck_src, zck_tgt)) + zckDL *dl = zck_dl_init(zck_tgt); + if(dl == NULL) exit(1); - int max_ranges = 256; - if(!zck_range_calc_segments(&(dl->info), max_ranges)) + dl->zck = zck_tgt; + + if(!dl_header(curl_ctx, dl, arguments.args[0], arguments.log_level)) exit(1); - lseek(dl->dst_fd, 0, SEEK_SET); - if(!zck_dl_range(dl, arguments.args[0])) + if(!zck_copy_chunks(zck_src, zck_tgt)) exit(1); printf("Downloaded %lu bytes\n", (long unsigned)zck_dl_get_bytes_downloaded(dl)); int exit_val = 0; - switch(zck_hash_check_data(dl->zck, dl->dst_fd)) { + switch(zck_validate_data_checksum(dl->zck)) { case -1: exit_val = 1; break; @@ -180,6 +268,7 @@ int main (int argc, char *argv[]) { zck_dl_free(&dl); zck_free(&zck_tgt); zck_free(&zck_src); - zck_dl_global_cleanup(); + curl_easy_cleanup(curl_ctx); + curl_global_cleanup(); exit(exit_val); }